]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
shell/util: Add touch_file_async() helper
authorFlorian Müllner <fmuellner@gnome.org>
Mon, 23 Mar 2020 16:57:38 +0000 (17:57 +0100)
committerFlorian Müllner <florian.muellner@gmail.com>
Wed, 25 Mar 2020 20:03:01 +0000 (20:03 +0000)
Add a small helper method to asynchronously "touch" a file and return
whether the file was created or not.

As g_file_make_directory_with_parents() doesn't have an async variant,
we need a C helper to make the entire operation non-blocking.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2432

src/shell-util.c
src/shell-util.h

index 26ff66e4eff7b715a5ebf8111f8a9be17325e824..d1a75bc6b42ca3cab058d9223fa9e9bb53d0650c 100644 (file)
@@ -291,6 +291,68 @@ shell_get_file_contents_utf8_sync (const char *path,
   return contents;
 }
 
+static void
+touch_file (GTask        *task,
+            gpointer      object,
+            gpointer      task_data,
+            GCancellable *cancellable)
+{
+  GFile *file = object;
+  g_autoptr (GFile) parent = NULL;
+  g_autoptr (GFileOutputStream) stream = NULL;
+  GError *error = NULL;
+
+  parent = g_file_get_parent (file);
+  g_file_make_directory_with_parents (parent, cancellable, &error);
+
+  if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
+    {
+      g_task_return_error (task, error);
+      return;
+    }
+  g_clear_error (&error);
+
+  stream = g_file_create (file, G_FILE_CREATE_NONE, cancellable, &error);
+
+  if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
+    {
+      g_task_return_error (task, error);
+      return;
+    }
+  g_clear_error (&error);
+
+  if (stream)
+    g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, NULL);
+
+  g_task_return_boolean (task, stream != NULL);
+}
+
+void
+shell_util_touch_file_async (GFile               *file,
+                             GAsyncReadyCallback  callback,
+                             gpointer             user_data)
+{
+  g_autoptr (GTask) task = NULL;
+
+  g_return_if_fail (G_IS_FILE (file));
+
+  task = g_task_new (file, NULL, callback, user_data);
+  g_task_set_source_tag (task, shell_util_touch_file_async);
+
+  g_task_run_in_thread (task, touch_file);
+}
+
+gboolean
+shell_util_touch_file_finish (GFile         *file,
+                              GAsyncResult  *res,
+                              GError       **error)
+{
+  g_return_val_if_fail (G_IS_FILE (file), FALSE);
+  g_return_val_if_fail (G_IS_TASK (res), FALSE);
+
+  return g_task_propagate_boolean (G_TASK (res), error);
+}
+
 /**
  * shell_util_wifexited:
  * @status: the status returned by wait() or waitpid()
index 99b9350f97a2f97a812627b9cf75376d77cee7c5..055e881905ab7be0dd6cf4b97a22dfc3626f3640 100644 (file)
@@ -30,6 +30,13 @@ gboolean shell_write_string_to_stream          (GOutputStream    *stream,
 char    *shell_get_file_contents_utf8_sync     (const char       *path,
                                                 GError          **error);
 
+void     shell_util_touch_file_async           (GFile               *file,
+                                                GAsyncReadyCallback  callback,
+                                                gpointer             user_data);
+gboolean shell_util_touch_file_finish          (GFile               *file,
+                                                GAsyncResult        *res,
+                                                GError             **error);
+
 gboolean shell_util_wifexited                  (int               status,
                                                 int              *exit);